﻿using System;
using System.Collections.Generic;
using System.Linq;
using DiagnosisToolBL;
using com.diagnosis.tool.xml;

namespace com.diagnosis.tool.bl
{
    public class GetDiseasesFromXML : BasicGetDiseases
    {        
        private Dictionary<String, int> mSymptomNameToID;

        private readonly String mFilePath = @"C:\projects\DiagnosisData.xml";

        public GetDiseasesFromXML(Object pInitData)
        {
            fillMap();

            if (pInitData != null)
            {
                mFilePath = (String) pInitData;
            }
        }

        public override ExtendedDiseaseForDisplay[] GetDiseases(String[] pSymptomsToCheck)
        {
            var fittedDiseases = new List<ExtendedDiseaseForDisplay>();

            DiagnosisToolXmlMngr xmlMngr = DiagnosisToolXmlMngr.GetInstance(mFilePath);
            DiagnosisToolData toolData = xmlMngr.DiagnosisToolData;
            Disease[] diseases = toolData.Diseases;

            int[] manSymptomsIdsToCheck;
            int[] nonManSymptomsIdsToCheck;
            ConvertSymptomsToCheckToIds(
                pSymptomsToCheck, 
                out manSymptomsIdsToCheck, 
                out nonManSymptomsIdsToCheck);
            
            foreach (Disease curDisease in diseases)
            {
                ExtendedDiseaseForDisplay extendedDiseaseForDisplay =
                    CheckDisease(curDisease, manSymptomsIdsToCheck, nonManSymptomsIdsToCheck);
                if (null != extendedDiseaseForDisplay)
                {
                    fittedDiseases.Add(extendedDiseaseForDisplay);
                }
            }
            var res = fittedDiseases.ToArray();
            Array.Sort(res);
            return res;
        }

        private ExtendedDiseaseForDisplay CheckDisease(
            Disease pDisease, 
            int[] pManSymptomsIdsToCheck,
            int[] pNonManSymptomsIdsToCheck)
        {
            ExtendedDiseaseForDisplay res = null;
            
            var hitNumber   = 0;
            var missNumber  = 0;

            int[] diseasesSymptomsIds = pDisease.SymptomIDS;

            // Check mandatory
            foreach (var curSymptIdToCheck in pManSymptomsIdsToCheck)
            {
                if (!diseasesSymptomsIds.Contains(curSymptIdToCheck))
                {
                    return null;
                }
            }

            hitNumber = pManSymptomsIdsToCheck.Length;

            foreach (var curSymptIDToCheck in pNonManSymptomsIdsToCheck)
            {
                if (diseasesSymptomsIds.Contains(curSymptIDToCheck))
                {
                    hitNumber++;
                }
                else
                {
                    missNumber++;
                }
            }

            if (hitNumber > 0)
            {
                res = 
                    new ExtendedDiseaseForDisplay(
                        pDisease, 
                        hitNumber, 
                        missNumber,
                        pManSymptomsIdsToCheck.Length + 
                        pNonManSymptomsIdsToCheck.Length);
            }

            return res;
        }

        private void ConvertSymptomsToCheckToIds(
            string[]     pSymptomsToCheck,
            out int[]    pManSymptomsIdsToCheck,
            out int[]    pNonManSymptomsIdsToCheck )
        {
            var         manIds      = new List<int>();
            var         nonManIds   = new List<int>();
            List<int>   refList     = null;

            for (int i = 0; i < pSymptomsToCheck.Length; i++)
            {
                Boolean isMan = false;
                String checkValue = pSymptomsToCheck[i];
                refList = nonManIds;
                if (checkValue.StartsWith("*"))
                {
                    isMan = true;
                    checkValue = checkValue.Substring("*".Length);
                    refList = manIds;
                }
                int id = this.mSymptomNameToID[checkValue];
                refList.Add(id);
            }

            pManSymptomsIdsToCheck = manIds.ToArray();
            pNonManSymptomsIdsToCheck = nonManIds.ToArray();
        }

        public override String[] GetSymptoms(String pStringToFind, int pNumberOfSymptomsToReturn)
        {
            List<String> symptomsNames = new List<String>();
            Dictionary<String, int>.KeyCollection allSymptomsNames = mSymptomNameToID.Keys;

            bool breakSearch = false;
            foreach (String curSymptomName in allSymptomsNames)
            {
                if (curSymptomName.ToUpper().Contains(pStringToFind.ToUpper()))
                {
                    symptomsNames.Add(curSymptomName);
                    if (symptomsNames.Count >= pNumberOfSymptomsToReturn)
                    {
                        breakSearch = true;
                        break;
                    }
                }
                if (breakSearch) break;
            }

            return symptomsNames.ToArray();
        }

        private void fillMap()
        {
            mSymptomNameToID = new Dictionary<string, int>();

            DiagnosisToolXmlMngr xmlMngr = DiagnosisToolXmlMngr.GetInstance(mFilePath);
            DiagnosisToolData toolData = xmlMngr.DiagnosisToolData;

            foreach (SameSymptoms curSameSymp in toolData.SameSymptoms)
            {
                foreach (String curSymp in curSameSymp.Symptoms)
                {
                    mSymptomNameToID.Add(curSymp, curSameSymp.SymptomID);
                }
            }
        }
    }
}

